<template>
  <div class="voice-to-text-page">
    <!-- 头部区域 -->
    <el-page-header
      @back="goBack"
      :icon="ArrowLeft"
      class="voice-to-text-header"
    >
    <template #content>
      <span class="text-large font-900 mr-3"> 实时录音转文字 </span>
      </template>
      <template #extra>
        <div @click="startRecording">
          <span v-if="!isConnected" class="connection-status disconnected"
            >未连接</span
          >
          <span v-else class="connection-status connected">已连接</span>
        </div>
      </template>
    </el-page-header>

    <!-- 内容区域 -->
    <div class="voice-to-text-content">
      <el-card>
        <!-- 说话者信息 -->
        <div class="speaker-info">
          <div class="speaker-avatar" :class="{ recording: isRecording }">
            <el-icon><User /></el-icon>
            <div class="recording-indicator" v-if="isRecording">
              <div class="pulse-ring"></div>
            </div>
          </div>
          <div class="timestamp">{{ currentTime }}</div>
        </div>

        <!-- 文本内容 -->
        <div class="text-content">
          <!-- 最终转录文本段落 -->
          <div v-if="finalTranscript" class="final-text">
            <div class="text-label">转录结果：</div>
            <div class="transcript-text">{{ finalTranscript }}</div>
            <div class="typing-cursor" v-if="isTyping"></div>
          </div>
          
          <!-- 临时转录文本（流式显示） -->
          <div v-if="interimTranscript && !finalTranscript" class="interim-text">
            <div class="text-label">正在识别：</div>
            <div class="transcript-text interim">{{ interimTranscript }}</div>
            <div class="typing-cursor" v-if="isTyping"></div>
          </div>
          
          <!-- 占位符 -->
          <div v-if="!finalTranscript && !interimTranscript" class="placeholder-text">
            点击开始录音，<br>
            语音将实时转换为文字显示在这里...
          </div>
        </div>
      </el-card>
    </div>

    <!-- 录音状态显示 -->
    <div class="recording-status-info" v-if="isRecording">
      <div class="status-indicator">
        <div class="pulse-dot" :class="{ paused: isPaused }"></div>
        <span>{{ isPaused ? "录音已暂停" : "正在录音中..." }}</span>
      </div>
      <div class="recording-time">
        <el-icon><Clock /></el-icon>
        {{ formatTime(recordingTime) }}
      </div>
    </div>

    <!-- 实时状态显示 -->
    <!-- <div class="real-time-status" v-if="isRecording">
      <div class="status-item">
        <el-icon><Upload /></el-icon>
        <span>音频数据发送中...</span>
      </div>
      <div class="status-item" v-if="lastTranscriptTime">
        <el-icon><Download /></el-icon>
        <span>最后接收: {{ lastTranscriptTime }}</span>
      </div>
      <div class="status-item">
        <el-icon><DataLine /></el-icon>
        <span>数据包: {{ audioDataCount }}</span>
      </div>
      <div class="status-item">
        <el-icon><Microphone /></el-icon>
        <span>音量: {{ Math.round(currentVolume * 100) }}%</span>
      </div>
    </div> -->

    <!-- 录音按钮区域  -->
    <div class="voice-to-text-record-button">
      <div class="button-container">
        <div
          class="circular-button start-button"
          :class="{ disabled: isPaused || !microphonePermission || wsStatus !== 'connected' }"
          @click="handleStartRecording"
          v-if="!isRecording"
        >
          <el-icon size="30"><Microphone /></el-icon>
        </div>
        <span class="button-text" v-if="!isRecording">开始录音</span>
      </div>

      <div class="button-container" v-if="isRecording && !isPaused">
        <div
          class="circular-button pause-button"
          @click="pauseRecording"
        >
          <el-icon size="30"><VideoPause /></el-icon>
        </div>
        <span class="button-text">暂停录音</span>
      </div>

      <div class="button-container" v-if="isRecording && isPaused">
        <div
          class="circular-button resume-button"
          @click="resumeRecording"
        >
          <el-icon size="30"><VideoPlay /></el-icon>
        </div>
        <span class="button-text">继续录音</span>
      </div>

      <div class="button-container" v-if="isRecording">
        <div
          class="circular-button stop-button"
          @click="handleStopRecording"
        >
          <el-icon size="30"><Close /></el-icon>
        </div>
        <span class="button-text">结束录音</span>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from "vue";
import { useRouter } from "vue-router";
import { 
  ArrowLeft, 
  User, 
  Clock, 
  Upload, 
  Download, 
  DataLine, 
  Microphone, 
  VideoPause, 
  VideoPlay, 
  Close 
} from "@element-plus/icons-vue";
import { ElMessage, ElMessageBox } from "element-plus";

const router = useRouter();
const goBack = () => {
  router.back();
};

// 状态变量
const isRecording = ref(false);
const isPaused = ref(false);
const recordingTime = ref(0);
const currentTime = ref("00:00");
const finalTranscript = ref("");
const interimTranscript = ref("");
const isTyping = ref(false);
const microphonePermission = ref(false);
const showPermissionNotice = ref(false);

// WebSocket相关
const websocket = ref<WebSocket | null>(null);
const wsStatus = ref<'disconnected' | 'connecting' | 'connected'>('disconnected');
const isConnected = ref(false);
const sessionId = ref("");

// 媒体流相关
let mediaStream: MediaStream | null = null;
let audioContext: AudioContext | null = null;
let processor: ScriptProcessorNode | null = null;

// 定时器
let recordingTimer: number | null = null;
let heartbeatTimer: number | null = null;
let reconnectTimer: number | null = null;
let sendTimer: number | null = null;

// 其他状态
const reconnectAttempts = ref(0);
const maxReconnectAttempts = 5;
const reconnectDelay = 5000;
const heartbeatInterval = 30000;
const lastTranscriptTime = ref<string | null>(null);
const audioDataCount = ref(0);

// 音频相关参数
const bufferSize = 1024;
const sampleRate = 16000;
const chunkSize = 1024;
const currentVolume = ref(0);
const volumeThreshold = 0.01;
const silenceDuration = ref(0);
const silenceThreshold = 2000;
let lastSoundTime = 0;
let isSilent = false;
let pendingAudioData: number[] = [];

// 生命周期钩子
onMounted(async () => {
  await requestMicrophonePermission();
  connectWebSocket();
});

onBeforeUnmount(() => {
  cleanup();
});

// 清理函数
const cleanup = () => {
  if (recordingTimer) clearInterval(recordingTimer);
  if (heartbeatTimer) clearInterval(heartbeatTimer);
  if (reconnectTimer) clearTimeout(reconnectTimer);
  if (sendTimer) clearTimeout(sendTimer);
  
  if (mediaStream) {
    mediaStream.getTracks().forEach((track) => track.stop());
  }
  
  if (websocket.value) {
    websocket.value.close();
  }
  
  if (audioContext) {
    audioContext.close();
  }
};

// WebSocket连接
const connectWebSocket = () => {
  try {
    wsStatus.value = "connecting";
    isConnected.value = false;
    sessionId.value = generateSessionId();

    const wsUrl = `ws://10.40.0.230:8009/realTime/audioStream`;
    console.log("尝试连接WebSocket:", wsUrl);

    websocket.value = new WebSocket(wsUrl);

    const connectionTimeout = setTimeout(() => {
      if (wsStatus.value === "connecting") {
        console.error("WebSocket连接超时");
        wsStatus.value = "disconnected";
        isConnected.value = false;
        websocket.value?.close();
        ElMessage.error("连接超时，请检查服务器地址和端口");
      }
    }, 10000);

    websocket.value.onopen = () => {
      clearTimeout(connectionTimeout);
      console.log("WebSocket连接已建立");
      wsStatus.value = "connected";
      isConnected.value = true;
      reconnectAttempts.value = 0;
      ElMessage.success("服务器连接成功");
      startHeartbeat();
    };

    websocket.value.onmessage = (event) => {
      try {
        const data = JSON.parse(event.data);
        handleWebSocketMessage(data);
      } catch (error) {
        console.error("解析WebSocket消息失败:", error);
      }
    };

    websocket.value.onclose = (event) => {
      clearTimeout(connectionTimeout);
      console.log("WebSocket连接已关闭", event.code, event.reason);
      wsStatus.value = "disconnected";
      isConnected.value = false;
      stopHeartbeat();
      
      if (isRecording.value) {
        ElMessage.warning("服务器连接断开，录音已停止");
        stopRecording();
      }
      
      if (event.code !== 1000 && reconnectAttempts.value < maxReconnectAttempts) {
        scheduleReconnect();
      }
    };

    websocket.value.onerror = (error) => {
      clearTimeout(connectionTimeout);
      console.error("WebSocket连接错误:", error);
      wsStatus.value = "disconnected";
      isConnected.value = false;
      ElMessage.error("服务器连接失败");
    };
  } catch (error) {
    console.error("WebSocket连接失败:", error);
    wsStatus.value = "disconnected";
    isConnected.value = false;
    ElMessage.error("WebSocket连接失败");
  }
};

// 心跳机制
const startHeartbeat = () => {
  stopHeartbeat();
  heartbeatTimer = window.setInterval(() => {
    if (websocket.value && websocket.value.readyState === WebSocket.OPEN) {
      sendHeartbeat();
    } else {
      stopHeartbeat();
    }
  }, heartbeatInterval);
};

const stopHeartbeat = () => {
  if (heartbeatTimer) {
    clearInterval(heartbeatTimer);
    heartbeatTimer = null;
  }
};

const sendHeartbeat = () => {
  if (websocket.value && websocket.value.readyState === WebSocket.OPEN) {
    const heartbeatMessage = {
      type: "heartbeat",
      sessionId: sessionId.value,
      timestamp: Date.now(),
    };
    try {
      websocket.value.send(JSON.stringify(heartbeatMessage));
      console.log("发送心跳包");
    } catch (error) {
      console.error("发送心跳失败:", error);
      stopHeartbeat();
    }
  }
};

// 重连机制
const scheduleReconnect = () => {
  if (reconnectTimer) {
    clearTimeout(reconnectTimer);
  }
  
  reconnectAttempts.value++;
  const delay = reconnectDelay * Math.pow(2, reconnectAttempts.value - 1);
  
  console.log(`第${reconnectAttempts.value}次重连，${delay}ms后重连`);
  
  reconnectTimer = window.setTimeout(() => {
    if (wsStatus.value !== 'connected') {
      console.log("尝试重连WebSocket");
      connectWebSocket();
    }
  }, delay);
};

// 处理WebSocket消息
const handleWebSocketMessage = (data: any) => {
  console.log("收到服务器消息:", data);
  
  if (data.text && data.text.trim()) {
    console.log("处理转录文本:", data.text);
    updateTranscript(data.text);
    lastTranscriptTime.value = new Date().toLocaleTimeString();
  }
};

// 更新转录文本
const updateTranscript = (text: string) => {
  if (text && text.trim()) {
    if (interimTranscript.value) {
      finalTranscript.value += interimTranscript.value;
      interimTranscript.value = "";
    }
    
    finalTranscript.value += text;
    formatTranscriptAsParagraph();
    
    isTyping.value = true;
    setTimeout(() => {
      isTyping.value = false;
    }, 1000);
  }
};

// 格式化转录文本为段落
const formatTranscriptAsParagraph = () => {
  if (!finalTranscript.value) return;
  
  const text = finalTranscript.value.trim();
  if (text && !text.match(/[。！？.!?]$/)) {
    finalTranscript.value = text + ',';
  }
};

// 生成会话ID
const generateSessionId = () => {
  return "session_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
};

// 请求麦克风权限
const requestMicrophonePermission = async () => {
  try {
    if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
      ElMessage.error("您的浏览器不支持麦克风功能");
      return false;
    }

    const stream = await navigator.mediaDevices.getUserMedia({
      audio: {
        sampleRate: 16000,
        channelCount: 1,
        echoCancellation: true,
        noiseSuppression: true,
      } as any,
    });

    microphonePermission.value = true;
    showPermissionNotice.value = false;
    ElMessage.success("麦克风权限已获取");

    stream.getTracks().forEach((track) => track.stop());
    return true;
  } catch (error: any) {
    console.error("麦克风权限申请失败:", error);
    microphonePermission.value = false;
    showPermissionNotice.value = true;
    ElMessage.error("麦克风权限申请失败: " + error.message);
    return false;
  }
};

// 处理开始录音点击
const handleStartRecording = () => {
  if (isPaused.value || !microphonePermission.value || wsStatus.value !== 'connected') {
    return;
  }
  startRecording();
};

// 开始录音
const startRecording = async () => {
  if (!microphonePermission.value) {
    const hasPermission = await requestMicrophonePermission();
    if (!hasPermission) return;
  }

  if (wsStatus.value !== "connected") {
    ElMessage.error("服务器未连接，无法开始录音");
    return;
  }

  try {
    mediaStream = await navigator.mediaDevices.getUserMedia({
      audio: {
        sampleRate: 16000,
        channelCount: 1,
        echoCancellation: true,
        noiseSuppression: true,
      } as any,
    });

    audioContext = new (window.AudioContext || (window as any).webkitAudioContext)({
      sampleRate: 16000,
    });

    const source = audioContext.createMediaStreamSource(mediaStream);
    processor = audioContext.createScriptProcessor(bufferSize, 1, 1);

    processor.onaudioprocess = (event) => {
      if (
        isRecording.value &&
        !isPaused.value &&
        websocket.value &&
        websocket.value.readyState === WebSocket.OPEN
      ) {
        const audioData = event.inputBuffer.getChannelData(0);
        processAudioData(audioData);
      }
    };

    source.connect(processor);
    processor.connect(audioContext.destination);

    isRecording.value = true;
    isPaused.value = false;
    recordingTime.value = 0;
    startTimer();

    ElMessage.success("开始录音");
  } catch (error: any) {
    console.error("开始录音失败:", error);
    ElMessage.error("开始录音失败: " + error.message);
  }
};

// 处理音频数据
const processAudioData = (audioData: Float32Array) => {
  const volume = calculateVolume(audioData);
  currentVolume.value = volume;
  
  const hasSound = volume > volumeThreshold;
  const currentTimestamp = Date.now();
  
  if (hasSound) {
    isSilent = false;
    silenceDuration.value = 0;
    lastSoundTime = currentTimestamp;
    
    const int16Data = convertFloat32ToInt16(audioData);
    pendingAudioData.push(...Array.from(int16Data));
    
    if (sendTimer) clearTimeout(sendTimer);
    
    sendTimer = window.setTimeout(() => {
      sendPendingAudioData();
    }, 100);
  } else {
    silenceDuration.value = currentTimestamp - lastSoundTime;
    
    if (silenceDuration.value > silenceThreshold && pendingAudioData.length > 0) {
      sendPendingAudioData();
      isSilent = true;
    }
  }
};

// 计算音量
const calculateVolume = (audioData: Float32Array) => {
  let sum = 0;
  for (let i = 0; i < audioData.length; i++) {
    sum += audioData[i] * audioData[i];
  }
  return Math.sqrt(sum / audioData.length);
};

// 发送待发送的音频数据
const sendPendingAudioData = () => {
  if (pendingAudioData.length === 0) return;
  
  while (pendingAudioData.length >= chunkSize) {
    const chunk = pendingAudioData.splice(0, chunkSize);
    const alignedChunk = alignToMultipleOf4(chunk);
    sendAudioChunk(alignedChunk);
  }
  
  if (sendTimer) {
    clearTimeout(sendTimer);
    sendTimer = null;
  }
};

// 确保数据长度是4的倍数
const alignToMultipleOf4 = (data: number[]) => {
  const remainder = data.length % 4;
  if (remainder === 0) return data;
  
  const padding = 4 - remainder;
  const alignedData = [...data];
  for (let i = 0; i < padding; i++) {
    alignedData.push(0);
  }
  
  return alignedData;
};

// 发送音频数据块
const sendAudioChunk = (chunk: number[]) => {
  if (websocket.value && websocket.value.readyState === WebSocket.OPEN) {
    try {
      const int16Array = new Int16Array(chunk);
      websocket.value.send(int16Array.buffer);
      audioDataCount.value++;
      console.log(`发送音频数据块: ${chunk.length} 字节`);
    } catch (error) {
      console.error("发送音频数据失败:", error);
      ElMessage.error("音频数据发送失败");
    }
  }
};

// 转换Float32Array为Int16Array
const convertFloat32ToInt16 = (buffer: Float32Array) => {
  const l = buffer.length;
  const buf = new Int16Array(l);
  for (let i = 0; i < l; i++) {
    buf[i] = Math.min(1, buffer[i]) * 0x7FFF;
  }
  return buf;
};

// 暂停录音
const pauseRecording = () => {
  isPaused.value = true;
  stopTimer();
  ElMessage.info("录音已暂停");
};

// 继续录音
const resumeRecording = () => {
  isPaused.value = false;
  startTimer();
  ElMessage.info("继续录音");
};

// 停止录音
const stopRecording = () => {
  isRecording.value = false;
  isPaused.value = false;
  stopTimer();
  isTyping.value = false;

  if (mediaStream) {
    mediaStream.getTracks().forEach((track) => track.stop());
    mediaStream = null;
  }

  if (audioContext) {
    audioContext.close();
    audioContext = null;
  }

  if (processor) {
    processor.disconnect();
    processor = null;
  }

  pendingAudioData = [];
  
  if (sendTimer) {
    clearTimeout(sendTimer);
    sendTimer = null;
  }

  ElMessage.success("录音已结束");
};

// 处理结束录音确认
const handleStopRecording = async () => {
  try {
    await ElMessageBox.confirm(
      '确定要结束录音吗？',
      '确认结束录音',
      {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning',
      }
    );
    
    // 用户确认后执行停止录音
    stopRecording();
    
    router.push({
      path: '/file',
      query: {
        activeName: 'second'
      }
    });
    
  } catch {
    // 用户取消，不执行任何操作
  }
};

// 定时器相关
const startTimer = () => {
  recordingTimer = window.setInterval(() => {
    if (!isPaused.value) {
      recordingTime.value++;
      currentTime.value = formatTime(recordingTime.value);
    }
  }, 1000);
};

const stopTimer = () => {
  if (recordingTimer) {
    clearInterval(recordingTimer);
    recordingTimer = null;
  }
};

const formatTime = (seconds: number) => {
  const hours = Math.floor(seconds / 3600);
  const minutes = Math.floor((seconds % 3600) / 60);
  const secs = seconds % 60;

  if (hours > 0) {
    return `${hours.toString().padStart(2, "0")}:${minutes
      .toString()
      .padStart(2, "0")}:${secs.toString().padStart(2, "0")}`;
  } else {
    return `${minutes.toString().padStart(2, "0")}:${secs
      .toString()
      .padStart(2, "0")}`;
  }
};
</script>

<style lang="scss" scoped>
.voice-to-text-page {
  width: 100%;
  height: 100vh;
  padding: 20px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
}

.voice-to-text-header {
  flex-shrink: 0;
    :deep(.el-page-header__content) {
        font-size:16px;
        font-weight: 600;
  }
}

.connection-status {
  display: inline-flex;
  align-items: center;
  color: #868686;
  font-size: 14px;

  &::before {
    content: "";
    width: 5px;
    height: 5px;
    border-radius: 50%;
    margin-right: 6px;
  }

  &.disconnected::before {
    background-color: #ff4d4f;
  }

  &.connected::before {
    background-color: #52c41a;
  }
}

.voice-to-text-content {
  flex: 1;
  margin: 20px 0;
//   overflow: hidden;
  
  :deep(.el-card) {
    height: 100%;
    overflow-y: auto;
  }
}

.voice-to-text-record-button {
  flex-shrink: 0;
  display: flex;
  justify-content: center;
  gap: 12px;
  flex-wrap: wrap;
}

// 圆形按钮样式
.button-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

.circular-button {
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 50%;
  font-weight: 500;
  transition: all 0.3s ease;
  width: 80px;
  height: 80px;
  box-sizing: border-box;
  
  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  }
  
  &:active {
    transform: translateY(0);
  }
  
  &.disabled {
    cursor: not-allowed;
    opacity: 0.6;
    
    &:hover {
      transform: none;
      box-shadow: none;
    }
  }
}

.button-text {
  font-size: 14px;
  color: #333;
  text-align: center;
}

// 开始录音按钮
.start-button {
  background: linear-gradient(135deg, #67c23a, #85ce61);
  color: white;
  
  &:hover:not(.disabled) {
    background: linear-gradient(135deg, #5daf34, #7bc855);
  }
}

// 暂停录音按钮
.pause-button {
  background: linear-gradient(135deg, #e6a23c, #f0c78a);
  color: white;
  
  &:hover {
    background: linear-gradient(135deg, #d4922b, #e6b366);
  }
}

// 继续录音按钮
.resume-button {
  background: linear-gradient(135deg, #409eff, #79bbff);
  color: white;
  
  &:hover {
    background: linear-gradient(135deg, #337ecc, #66b3ff);
  }
}

// 结束录音按钮
.stop-button {
  background: linear-gradient(135deg, #f56c6c, #f89898);
  color: white;
  
  &:hover {
    background: linear-gradient(135deg, #f45454, #f67c7c);
  }
}

// 新增样式 - 说话者信息
.speaker-info {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid #e5e7eb;
}

.speaker-avatar {
  width: 32px;
  height: 32px;
  background: #e5e7eb;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #6b7280;
  position: relative;
  transition: all 0.3s;
  
  &.recording {
    background: #ef4444;
    color: white;
  }
}

.recording-indicator {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 40px;
  height: 40px;
}

.pulse-ring {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 20px;
  height: 20px;
  border: 2px solid #ef4444;
  border-radius: 50%;
  animation: pulse 1.5s infinite;
}

@keyframes pulse {
  0% {
    transform: translate(-50%, -50%) scale(0.8);
    opacity: 1;
  }
  100% {
    transform: translate(-50%, -50%) scale(1.5);
    opacity: 0;
  }
}

.timestamp {
  color: #6b7280;
  font-size: 14px;
  font-weight: 500;
}

// 文本内容样式
.text-content {
  color: #374151;
  font-size: 14px;
  line-height: 1.6;
  position: relative;
  min-height: 200px;
}

.final-text, .interim-text {
  margin-bottom: 16px;
}

.text-label {
  font-size: 12px;
  color: #6b7280;
  margin-bottom: 8px;
  font-weight: 500;
}

.transcript-text {
  white-space: pre-wrap;
  word-wrap: break-word;
  font-size: 16px;
  line-height: 1.8;
  text-align: justify;
  
  &.interim {
    color: #6b7280;
    font-style: italic;
    border-bottom: 2px solid #e5e7eb;
    padding-bottom: 8px;
  }
}

.placeholder-text {
  color: #9ca3af;
  text-align: center;
  padding: 40px 0;
}

.typing-cursor {
  display: inline-block;
  width: 2px;
  height: 16px;
  background: #3b82f6;
  margin-left: 2px;
  animation: blink 1s infinite;
}

@keyframes blink {
  0%, 50% {
    opacity: 1;
  }
  51%, 100% {
    opacity: 0;
  }
}

// 录音状态显示
.recording-status-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  background: #fef3c7;
  border-radius: 8px;
  margin-bottom: 16px;
  flex-shrink: 0;
}

.status-indicator {
  display: flex;
  align-items: center;
  gap: 8px;
}

.pulse-dot {
  width: 8px;
  height: 8px;
  background: #ef4444;
  border-radius: 50%;
  animation: pulse-dot 1s infinite;
  
  &.paused {
    background: #f59e0b;
    animation: none;
  }
}

@keyframes pulse-dot {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.2);
  }
  100% {
    transform: scale(1);
  }
}

.recording-time {
  display: flex;
  align-items: center;
  gap: 6px;
  color: #6b7280;
  font-size: 14px;
}

// 实时状态显示
.real-time-status {
  display: flex;
  justify-content: center;
  gap: 24px;
  padding: 12px;
  background: #f8f9fa;
  border-radius: 6px;
  margin-bottom: 16px;
  flex-shrink: 0;
  flex-wrap: wrap;
}

.status-item {
  display: flex;
  align-items: center;
  gap: 6px;
  color: #6b7280;
  font-size: 14px;
}

// 响应式设计
@media (max-width: 768px) {
  .voice-to-text-record-button {
    display: felx;
    gap: 8px;
  }

  .real-time-status {
    flex-direction: column;
    gap: 8px;
  }
}
</style>
